<?php
/**
 * @author		João Batista Neto
 * @brief		Objetos que representam cada tipo do retorno da API
 * @package		dso.buscape.result.type
 */

require_once 'dso/buscape/result/type/BuscapeComposite.php';

/**
 * @brief		Produto
 * @details		Produtos BuscaPé
 * @class		BuscapeProduct
 * @ingroup		Types
 */
class BuscapeProduct extends BuscapeComposite {
	/**
	 * @brief	ID do produto
	 * @var		integer
	 */
	private $id;

	/**
	 * @brief	ID da categoria do produto
	 * @var		integer
	 */
	private $categoryId;

	/**
	 * @brief	Total de vendedores do produto
	 * @var		integer
	 */
	private $totalSellers;

	/**
	 * @brief	Indica se existe uma descrição completa do produto
	 * @var		boolean
	 */
	private $fullDescription;

	/**
	 * @brief	Nome completo do produto
	 * @var		string
	 */
	private $productName;

	/**
	 * @brief	Nome curto do produto
	 * @var		string
	 */
	private $productShortName;

	/**
	 * @brief	Moeda do preço retornado
	 * @var		BuscapeCurrency
	 */
	private $currency;

	/**
	 * @brief	Menor preço do produto
	 * @var		float
	 */
	private $priceMin;

	/**
	 * @brief	Maior preço do produto
	 * @var		float
	 */
	private $priceMax;

	/**
	 * @brief	Links do produto
	 * @var		RecursiveComponentIterator
	 */
	private $links;

	/**
	 * @brief	Imagem do produto
	 * @var		BuscapeThumbnail
	 */
	private $thumbnail;

	/**
	 * @brief	Avaliações do produto
	 * @var		BuscapeRating
	 */
	private $rating;

	/**
	 * @brief	Especificações do produto
	 * @var		BuscapeSpecification
	 */
	private $specification;

	/**
	 * @brief	Verifica se um filho é aceitável pelo componente
	 * @param	$child BuscapeComponent
	 * @return	boolean
	 * @see		BuscapeComponent.accept()
	 */
	protected function accept( IObject $child ){
		if ( parent::accept( $child ) ){
			$reflection = $child->getClass();

			return $reflection->getName() == 'BuscapeOffer' || $reflection->isSubclassOf( 'BuscapeOffer' );
		}

		return false;
	}

	/**
	 * @brief	Adiciona um novo link ao produto.
	 * @param	$link BuscapeLink O link que será adicionado.
	 * @return	BuscapeProduct Este produto
	 */
	public function addLink( BuscapeLink $link ){
		if ( is_null( $this->links ) ){
			$this->links = new RecursiveComponentIterator();
		}

		$this->links->append( $link );

		return $this;
	}

	/**
	 * @brief	Adiciona uma nova oferta ao produto
	 * @param	$offer BuscapeOffer
	 * @return	BuscapeProduct Este produto
	 * @see		Component.add()
	 */
	public function addOffer( BuscapeOffer $offer ){
		$this->add( $offer );

		return $this;
	}

	/**
	 * @brief	Cria uma instância do objeto com os argumentos passados
	 * @param	$args array Lista de argumentos que serão utilizados para criação do objeto
	 * @return	BuscapeProduct
	 */
	public static function createInstance( array $args ){
		$product = new BuscapeProduct();

		foreach ( $args as $property => $value ){
			$product->$property = $value;
		}


		return $product;
	}

	/**
	 * @brief	Recupera o ID do produto
	 * @return	integer
	 */
	public function getId() {
		return $this->id;
	}

	/**
	 * @brief	Recupera o ID da categoria
	 * @return	integer
	 */
	public function getCategoryId() {
		return $this->categoryId;
	}

	/**
	 * @brief	Recupera o total de vendedores desse produto
	 * @return	integer
	 */
	public function getTotalSellers() {
		return $this->totalSellers;
	}

	/**
	 * @brief	Recupera o nome do produto
	 * @return	string
	 */
	public function getName() {
		return $this->productName;
	}

	/**
	 * @brief	Recupera o nome curto do produto
	 * @return	string
	 */
	public function getShortName() {
		return $this->productShortName;
	}

	/**
	 * @return the $currency
	 */
	public function getCurrency() {
		return $this->currency;
	}

	/**
	 * @return the $priceMin
	 */
	public function getPriceMin() {
		return $this->priceMin;
	}

	/**
	 * @return the $priceMax
	 */
	public function getPriceMax() {
		return $this->priceMax;
	}

	/**
	 * @brief	Recupera um iterator para os links
	 * @return	RecursiveComponentIterator
	 * @throws	BadMethodCallException Se não houverem links
	 */
	public function getLinks(){
		if ( !is_null( $this->links ) ){
			return $this->links->getIterator();
		} else {
			throw new BadMethodCallException( 'Não existem links para serem retornados.' );
		}
	}

	/**
	 * @brief	Recupera a imagem do produto
	 * @return	BuscapeThumbnail
	 */
	public function getThumbnail() {
		return $this->thumbnail;
	}

	/**
	 * @brief	Recupera a avaliação do produto
	 * @return	BuscapeRating
	 */
	public function getRating() {
		return $this->rating;
	}

	/**
	 * @brief	Recupera a especificação do produto
	 * @return	BuscapeSpecification
	 */
	public function getSpecification() {
		return $this->specification;
	}

	/**
	 * @brief	Verifica se o produto possui uma descrição completa
	 * @return	boolean
	 */
	public function hasFullDescription() {
		return $this->fullDescription;
	}
}